<template>
  <div
    class="merak-table-column-setting"
    :style="{
      top: `${top}px`,
      height: `calc(100% - ${top + 8}px)`
    }"
  >
    <div class="merak-table-column-setting--content">
      <div class="merak-table-column-setting--box">
        <div class="merak-table-column-setting--title">
          <h3>{{ $t("merak.has_table_header") }}</h3>
          <span>{{ $t("merak.permit_table") }}</span>
          <span>{{ $t("merak.drag") }}</span>
          <span>{{ $t("merak.change_table_sort") }}</span>
        </div>
        <Draggable
          class="merak-table-column-setting--card"
          handle=".merak-table-column-setting--handle"
          item-key="id"
          :list="visibleColumns"
          @change="handleDragChange"
        >
          <template #header>
            <div v-for="column in disabledColumns" class="merak-table-column-setting--tag merak-table-column-setting--disabled">
              <span>{{ column.title }}</span>
            </div>
          </template>
          <template #item="{ element }">
            <div class="merak-table-column-setting--tag">
              <span class="merak-table-column-setting--handle">{{ element.title }}</span>
              <MerakIcon @click="() => handleVisible(false, element)">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                  <path
                    d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
                  />
                </svg>
              </MerakIcon>
              <!-- <span @click="() => handleVisible(false, element)">X</span> -->
            </div>
          </template>
        </Draggable>
      </div>
      <el-divider />
      <div class="merak-table-column-setting--box">
        <div class="merak-table-column-setting--title">
          <h3>{{ $t("merak.no_choose_header") }}</h3>
        </div>
        <div class="merak-table-column-setting--card">
          <div
            v-for="column in hideColumns"
            class="merak-table-column-setting--tag merak-table-column-setting--hide"
            @click="() => handleVisible(true, column)"
          >
            <span>{{ column.title }}</span>
            <div class="merak-table-column-setting--mask">
              <MerakIcon size="14">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                  <path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
                </svg>
              </MerakIcon>
              <span>{{ $t("merak.add") }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="merak-table-column-setting--btns">
      <el-button size="small" @click="emit('close')">{{ $t("merak.cancel") }}</el-button>
      <el-button type="primary" size="small" @click="emit('change', columns)">{{ $t("merak.confirm") }}</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { MerakXTableColumn } from "./index";

import { ref, reactive, computed, onMounted, nextTick } from "vue";

import { ElDivider, ElButton } from "element-plus";

import MerakIcon from "@/components/MerakIcon/index.vue";

import Draggable from "vuedraggable";

const props = defineProps<{
  container: HTMLDivElement;
  columns: MerakXTableColumn[];
}>();

const emit = defineEmits<{
  close: [];
  change: [columns: MerakXTableColumn[]];
}>();

const top = ref(0);

const columns = reactive<MerakXTableColumn[]>([]);

const disabledColumns = computed(() => columns.filter(column => !!column.params?.disabled || !!column.fixed));

const visibleColumns = computed(() =>
  columns.filter(column => !column.fixed && !column.params?.disabled && column.visible != false)
);

const hideColumns = computed(() =>
  columns.filter(column => !column.fixed && !column.params?.disabled && column.visible === false)
);

const handleDragChange: InstanceType<typeof Draggable>["onDragUpdate"] = ({ moved }) => {
  const current = moved.element.field;
  const { oldIndex, newIndex } = moved;
  if (typeof current !== "string" || typeof oldIndex !== "number" || typeof newIndex !== "number") return;
  const moveIndex = oldIndex > newIndex ? newIndex + 1 : newIndex - 1;
  const target = visibleColumns.value?.[moveIndex];
  const targetIndex = columns.findIndex(column => column.field === target.field);
  const index = columns.findIndex(column => column.field === current);
  if (targetIndex !== -1 && index !== -1) {
    const column = columns.splice(index, 1)[0];
    columns.splice(targetIndex, 0, column);
  }
};

const handleVisible = (visible: boolean, col: MerakXTableColumn) => {
  const column = columns.find(column => column.field === col.field);
  if (!!column) {
    requestAnimationFrame(() => (column.visible = visible));
  }
};

// 火狐拖拽禁止打开新标签
const handleDropStop = (event: Event) => {
  event.stopPropagation();
};

onMounted(() => {
  columns.length = 0;
  props.columns.forEach(column => {
    columns.push({ ...column });
  });
  document.addEventListener("click", e => {
    const flag = (e.target as Element).closest(".merak-table-column-setting");
    if (!flag) {
      emit("close");
    }
  });
  document.body.ondrop = handleDropStop;
});

nextTick(() => {
  const header = props.container.querySelector(".vxe-table--header-wrapper");
  if (!header) return;
  const resizeObserver = new ResizeObserver(entries => {
    for (let entry of entries) {
      top.value = entry.contentRect.height;
    }
  });
  resizeObserver.observe(header);
});
</script>
